<?php

namespace App\Remote\Feishu\Departments;

use App\Exceptions\BaseException;
use App\Kuafu\User\Enum\UserCodeEnum;
use App\Remote\Feishu\User\TenantAccessTokenRemote;
use Closure;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\HttpFoundation\Request as RequestAlias;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;

class DepartmentsRemote extends Remote
{

    /**
     * @param string|null $departmentId
     * @param string $tenantAccessToken
     * @param bool $fetchChild
     * @param string $pageToken
     * @return mixed|void
     * @throws BaseException
     * @throws GuzzleException
     */
    public static function departments(
        ?string $departmentId,
        string $tenantAccessToken,
        bool $fetchChild = false,
        string $pageToken = ""
    ) {
        return self::customRequestV3(
            "/open-apis/contact/v3/departments?" . http_build_query([
                "department_id_type"   => "open_department_id",
                "parent_department_id" => $departmentId ?? 0,
                "fetch_child"          => $fetchChild,
                "page_size"            => 50,
                "page_token"           => $pageToken
            ]),
            RequestAlias::METHOD_GET,
            null,
            ["Authorization" => sprintf("Bearer %s", $tenantAccessToken)]
        );
    }

    /**
     * @param string $departmentId
     * @param string $tenantAccessToken
     * @return mixed
     * @throws BaseException
     * @throws GuzzleException
     */
    public static function parentDepartments(string $departmentId, string $tenantAccessToken)
    {
        return self::customRequestV3(
            "/open-apis/contact/v3/departments/parent?" . http_build_query([
                "department_id_type" => "open_department_id",
                "department_id"      => $departmentId,
                "page_size"          => 50,
            ]),
            RequestAlias::METHOD_GET,
            null,
            ["Authorization" => sprintf("Bearer %s", $tenantAccessToken)]
        );
    }

    /**
     * @param string $departmentId
     * @param string $tenantAccessToken
     * @return mixed
     * @throws BaseException
     * @throws GuzzleException
     */
    public static function departmentInfo(string $departmentId, string $tenantAccessToken)
    {
        return self::customRequestV3(
            "/open-apis/contact/v3/departments/{$departmentId}?" . http_build_query([
                "department_id_type" => "open_department_id",
                "department_id"      => $departmentId,
            ]),
            RequestAlias::METHOD_GET,
            null,
            ["Authorization" => sprintf("Bearer %s", $tenantAccessToken)]
        );
    }

    public static function approval(string $approval_code)
    {
        $tenantAccessToken = TenantAccessTokenRemote::accessToken(UserCodeEnum::MERCHANT_TYPE);
        $tenantAccessToken = $tenantAccessToken["tenant_access_token"];

        return self::customRequestV3(
            "/open-apis/approval/v4/approvals/{$approval_code}/subscribe",
            RequestAlias::METHOD_POST,
            null,
            ["Authorization" => sprintf("Bearer %s", $tenantAccessToken)]
        );
    }

    /**
     * @return Closure
     */
    public static function registerResponseHandle(): Closure
    {
        return function () {
            list($responseHttpCode, $responseContent) = func_get_args();
            if ($responseHttpCode != ResponseAlias::HTTP_OK) {
                throw new \Exception($responseContent);
            }

            if (isJson($responseContent)) {
                $responseArr = jsonToArr($responseContent);
                if ($responseArr["code"] != 0) {
                    throw new \Exception($responseArr["msg"]);
                }
                return $responseArr["data"];
            }

            throw new \Exception("[ $responseHttpCode ]-[ $responseContent ]");
        };
    }
}
